package org.summerframework.core.util.cmd;

import org.summerframework.core.base.result.DefaultResultCode;
import org.summerframework.core.exception.SystemException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.List;

/**
 * CmdExecuter
 *
 * @author YeKaiQiang
 * @date 2016/6/27
 */
public class CmdExecuter {

    private static final Log log = LogFactory.getLog(CmdExecuter.class);

    private static final ProcessBuilder builder = new ProcessBuilder();

    /**
     * 执行指令
     *
     * @param cmd    执行指令
     * @param getter 指令返回处理接口，若为null则不处理输出
     */
    static public int exec(List<String> cmd, ExecuterCallback getter) {
        return exec(cmd, getter, null);
    }

    /**
     * 执行指令
     *
     * @param cmd    执行指令
     * @param getter 指令返回处理接口，若为null则不处理输出
     */
    static public int exec(List<String> cmd, ExecuterCallback getter, File directory) {
        return exec(cmd, getter, directory, StandardCharsets.UTF_8);
    }

    /**
     * 执行指令
     *
     * @param cmd    执行指令
     * @param getter 指令返回处理接口，若为null则不处理输出
     */
    static public int exec(List<String> cmd, ExecuterCallback getter, File directory, Charset charset) {

        try {
            int count = 0;
            log.info(cmd);
            log.info(directory);
            if (directory != null) {
                builder.directory(directory);
            }
            builder.command(cmd);
            builder.redirectErrorStream(true);
            Process proc = builder.start();
            BufferedReader stdout = new BufferedReader(new InputStreamReader(proc.getInputStream(), charset));
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(proc.getOutputStream()));
            // 防止文件以创建卡死问题,默认覆盖
            bw.write("y\r\n");
            bw.flush();
            String line;

            while ((line = stdout.readLine()) != null) {
                log.debug(line);
                if (getter != null) {
                    getter.dealString(line);
                }
            }

            count = proc.waitFor();
            stdout.close();
            return count;
        } catch (Exception e) {
            throw new SystemException(DefaultResultCode.SYSTEM_ERROR, e);
        }
    }
}
